package com.zxhhyj.ui.view

import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.compositionLocalOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.unit.IntSize

val LocalTopBarState = compositionLocalOf { TopBarState() }

/**
 *
 */
@Composable
fun AppScaffold(
    modifier: Modifier,
    topBar: @Composable () -> Unit,
    content: @Composable () -> Unit
) {
    CompositionLocalProvider(LocalTopBarState provides rememberSaveable { TopBarState() }) {
        Box(modifier = modifier) {
            Box(
                modifier = Modifier
                    .bindTopBarState()
                    .fillMaxSize()
            ) {
                content.invoke()
            }
            topBar.invoke()
        }
    }
}

/**
 *
 */
@Composable
fun AppScaffold(
    modifier: Modifier,
    insetPaddingValues: PaddingValues = PaddingValues(),
    topBar: (@Composable () -> Unit)? = null,
    bottomNavigationBar: @Composable ColumnScope.() -> Unit,
    content: @Composable (PaddingValues) -> Unit
) {
    CompositionLocalProvider(LocalTopBarState provides rememberSaveable { TopBarState() }) {
        val layoutDirection = LocalLayoutDirection.current
        Box(
            modifier = modifier
        ) {
            var bottomBarSize by remember {
                mutableStateOf(IntSize.Zero)
            }
            if (topBar != null) {
                Box(
                    modifier = Modifier
                        .bindTopBarState()
                        .fillMaxSize()
                ) {
                    content.invoke(
                        PaddingValues(
                            top = insetPaddingValues.calculateTopPadding(),
                            bottom = with(LocalDensity.current) { bottomBarSize.height.toDp() },
                            start = insetPaddingValues.calculateLeftPadding(layoutDirection),
                            end = insetPaddingValues.calculateRightPadding(layoutDirection)
                        )
                    )
                }
                topBar.invoke()
            } else {
                content.invoke(
                    PaddingValues(
                        top = insetPaddingValues.calculateTopPadding(),
                        bottom = with(LocalDensity.current) { bottomBarSize.height.toDp() },
                        start = insetPaddingValues.calculateLeftPadding(layoutDirection),
                        end = insetPaddingValues.calculateRightPadding(layoutDirection)
                    )
                )
            }
            Column(
                modifier = Modifier
                    .fillMaxWidth()
                    .align(Alignment.BottomCenter)
                    .onSizeChanged {
                        bottomBarSize = it
                    }) {
                bottomNavigationBar()
            }
        }
    }
}